extends Node

#记得！！！！！！！！/f运行函数得有一个参数，是做动画的那个Tween！！！！！！！！函数结尾得<参数名>.playback_speed=1恢复Tween的动画！！！！！！！！！！！！！！！

var force_stopping=false#是否正在force_stop
var sms=false#Tween
var function_list=[]#/f<数字>执行函数列表
var pause_list=[]#每句话/f的/前一个字符位置
var function_num_list=[]#每句话从前向后依次,每个/f执行的函数在列表中的位置
var wait_list=[]#每句话/w的/前一个字符位置
var wait_num_list=[]#每句话从前向后依次,每个/w等待的时间在等待时间列表中的位置
var wait_time_list=[1,0.5,0.2,0.1,5]#/w<数字>等待时间列表
var speak_fragments=[]
var wait=false#每句话后是否等待
var curent_char=0#当前显示字符
var character_time0=0#每个字符等待时间
var dlg_td0=Thread.new()#对话线程
var function_td0=Thread.new()#/f执行函数线程
var wait_td0=Thread.new()#等待计时器线程
var lock=Semaphore.new()#对话锁
var dlgbox=false#对话框
var dlghead=false#对话角色头像
var dlg_s=false#对话框是否在加载字符

func dummy0(_a,_b,_c,_e):
	pass

func dummy():
	pass

func speak(SpeakFragments,functions):#([[<头像>,[[<对话文字>，<字间隔时间>，<是否等待>],..],...],...],[<函数0>,...])
	if(!sms):#_ready初始化比别处调用慢[恼]
		sms=Tween.new()
		add_child(sms)
		dlgbox=$"/root/Node2D_0/tdlg/dlg"
		dlghead=$"/root/Node2D_0/tdlg/spking"
	lock.post()
	force_stopping=true
	dlg_td0.wait_to_finish()
	force_stopping=false
	function_td0.wait_to_finish()
	wait_td0.wait_to_finish()
	lock=Semaphore.new()
	dlg_td0=Thread.new()
	function_td0=Thread.new()
	wait_td0=Thread.new()
	function_list=functions
	speak_fragments=SpeakFragments
	dlgbox.text=""#打开对话框
	dlgbox.show()
	sms.interpolate_property(dlgbox,"rect_size",Vector2(0,0),Vector2(940,240),1,Tween.TRANS_CUBIC,Tween.EASE_IN_OUT)
	sms.interpolate_property(dlgbox,"rect_position",Vector2(512,512),Vector2(78,264),1,Tween.TRANS_CUBIC,Tween.EASE_IN_OUT)
	dlghead.texture=SpeakFragments[0][0]
	sms.interpolate_property(dlghead,"position",Vector2(-32,296),Vector2(40,296),1,Tween.TRANS_CUBIC,Tween.EASE_IN_OUT)
	dlghead.show()
	sms.start()
	sms.connect("tween_all_completed",self,"start_dialogue_context")

func start_dialogue_context():
	print("if dlg_td is alive:",dlg_td0.is_active())
	dlg_td0.start(self,"dialogue_starts_now",speak_fragments)
	sms.connect("tween_all_completed",self,"dummy")

#[[t, [[您好,user0.我是system0,很高兴为您服务., 0.05, True], [这是您首次运行该程序,我将会为您创建新归档., 0.05, True]]]]

func dialogue_starts_now(spf):
	print("t")
	dlg_s=true
	sms.connect("tween_step",self,"dialogue_step")
	for t in spf:
		dlghead.texture=t[0]
		for t0 in t[1]:
			pause_list=[]
			wait_num_list=[]
			function_num_list=[]
			wait_list=[]
			#print("alll:",t0[0].length())
			var t1=0
			while(t0[0].ord_at(t1)!=0):#遍历对话字符串
				if(char(t0[0].ord_at(t1))=='/'&&t1<=t0[0].length()):
					match(char(t0[0].ord_at(t1+1))):
						'/':
							t0[0]=t0[0].left(t1+1)+t0[0].right(t1+2)#剪掉/后面那个/
						'f':
							pause_list.append(t1-1)
							var t2=t1+2
							while((t0[0].ord_at(t2))>=48&&(t0[0].ord_at(t2)<=57)):
								t2+=1
							var t4=0
							var t5=1
							for t3 in range(t2-1,t1+1,-1):
								t4+=(t0[0].ord_at(t3)-48)*t5
								t5*=10#获取/f后数字,存在t4
							function_num_list.append(t4)
							t0[0]=t0[0].left(t1)+t0[0].right(t2)#剪掉/f<数字>
						'w':
							wait_list.append(t1-1)
							var t2=t1+2
							while((t0[0].ord_at(t2))>=48&&(t0[0].ord_at(t2)<=57)):
								t2+=1
							var t4=0
							var t5=1
							for t3 in range(t2-1,t1+1,-1):
								t4+=(t0[0].ord_at(t3)-48)*t5
								t5*=10
							wait_num_list.append(t4)
							t0[0]=t0[0].left(t1)+t0[0].right(t2)
				t1+=1
			#print("txtl:",t0[0].length(),"\tfnl:",function_num_list,"\twnl:",wait_num_list,"\npl:",pause_list,"\twl:",wait_list,"\ntext:",t0[0])#########################################################################################################################################
			dlgbox.text=t0[0]
			dlgbox.visible_characters=0
			character_time0=t0[1]
			sms.interpolate_property(dlgbox,"visible_characters",0,dlgbox.text.length(),dlgbox.text.length()*character_time0,Tween.TRANS_LINEAR)
			if(t0[2]):#是否等待
				sms.connect("tween_all_completed",self,"is_wait")
			else:
				sms.connect("tween_all_completed",self,"no_wait")
			sms.start()
			lock.wait()
			if(force_stopping):
				break
		if(force_stopping):
			break
	if(!force_stopping):
		dlg_s=false
		dlgbox.text=""#关闭对话框
		sms.interpolate_property(dlgbox,"rect_size",Vector2(940,240),Vector2(0,0),1,Tween.TRANS_CUBIC,Tween.EASE_OUT)
		sms.interpolate_property(dlgbox,"rect_position",Vector2(78,264),Vector2(512,512),1,Tween.TRANS_CUBIC,Tween.EASE_OUT)
		sms.interpolate_property(dlghead,"position",Vector2(40,296),Vector2(-32,296),1,Tween.TRANS_CUBIC,Tween.EASE_OUT)
		sms.start()

func force_stop():#这个有问题!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!得手动复位dialogue.gd
	force_stopping=true
	sms.connect("tween_step",self,"dummy0")
	sms.connect("tween_all_completed",self,"dummy")
	sms.remove_all()
	lock.post()
	dlg_td0.wait_to_finish()
	function_td0.wait_to_finish()
	wait_td0.wait_to_finish()
	dlg_s=false
	dlgbox.text=""#关闭对话框
	sms.interpolate_property(dlgbox,"rect_size",Vector2(940,240),Vector2(0,0),1,Tween.TRANS_CUBIC,Tween.EASE_OUT)
	sms.interpolate_property(dlgbox,"rect_position",Vector2(78,264),Vector2(512,512),1,Tween.TRANS_CUBIC,Tween.EASE_OUT)
	sms.interpolate_property(dlghead,"position",Vector2(40,296),Vector2(-32,296),1,Tween.TRANS_CUBIC,Tween.EASE_OUT)
	sms.start()

func dialogue_step(_e0,_e1,_e2,_e3):#tween_step信号链接的函数自带4个参数必填
	curent_char=dlgbox.visible_characters-1
	if(pause_list.size()>0):#无元素数组不可访问[0]
		if(pause_list[0]==curent_char):#这里的if-elif-else逻辑要写完美好像只能用goto
			sms.playback_speed=0
			function_td0.start(self,"run_function",[function_list[function_num_list[0]],sms])#thread.start只能传一个参数[恼]
			function_td0.wait_to_finish()#这里不等的话下一次运行这次的还没跑完
			function_num_list.pop_front()
			pause_list.pop_front()
	if(wait_list.size()>0):
		if(wait_list[0]==curent_char):
			sms.playback_speed=0
			wait_td0.start(self,"wait_s",[wait_time_list[wait_num_list[0]],sms])
			wait_td0.wait_to_finish()
			wait_list.pop_front()
			wait_num_list.pop_front()

func wait_s(r):
	yield(get_tree().create_timer(r[0]),"timeout")
	r[1].playback_speed=1.0

func run_function(r):
	r[0].call_func(r[1])

func no_wait():
	lock.post()

func is_wait():
	wait=true

func _exit_tree():
	lock.post()
	#dlg_td0.wait_to_finish()
	if(function_td0.is_active()):
		function_td0.wait_to_finish()
	if(wait_td0.is_active()):
		wait_td0.wait_to_finish()

func _process(_delta):
	if(dlg_s):
		if(i.keys.accept)&&(dlgbox.visible_characters<dlgbox.text.length()):#跳过对话
			if(pause_list.size()>0):
				sms.remove(dlgbox,"visible_characters")
				dlgbox.visible_characters=pause_list[0]
				curent_char=pause_list[0]
				sms.interpolate_property(dlgbox,"visible_characters",pause_list[0],dlgbox.text.length(),(dlgbox.text.length()-pause_list[0])*character_time0,Tween.TRANS_LINEAR)
				sms.playback_speed=0
				sms.start()
				function_td0.start(self,"run_function",[function_list[function_num_list[0]],sms])
				function_td0.wait_to_finish()
				function_num_list.pop_front()
				pause_list.pop_front()
			else:
				dlgbox.visible_characters=dlgbox.text.length()
				sms.remove(dlgbox,"visible_characters")
	if(wait&&i.keys.accept):
		wait=false
		lock.post()
